<template>
    <div style="overflow: hidden;">
        <div id="graph" class="noselect full" style="background: #ddd;"></div>

        <SideDrawer ref="refDrawer" :width="300" :popout="bDrawerPopout">
            <div class="noselect" style="height:100%; overflow: hidden;">
                <!-- 侧边零件菜单 -->
                <PartLib v-show="sDrawerBody=='partlib'" :model=model @new-part="onNewPart"></PartLib>
                
                <!-- 侧边设置界面 -->
                <SideSetting ref="refSetting" v-show="sDrawerBody=='setting'" :model=model class="noselect" style="overflow: auto;"></SideSetting>
            </div>
            
            <template #toolbar>
                <div class="column gap10" style="margin-top: 10px; padding-left:5px; ">

                    <n-button class="toolbtn" circle size="large" v-show="bDrawerPopout" @click="bDrawerPopout=false">
                        <n-icon><ChevronLeft /></n-icon>
                    </n-button>

                    <n-button class="toolbtn" circle size="large" @click="openDrawer('partlib')">
                        <n-icon><PlusOutlined /></n-icon>
                    </n-button>

                    <n-button v-show="bCanvasActiveObject" class="toolbtn" circle size="large" @click="openDrawer('setting')" title="设置">
                        <n-icon><Options /></n-icon>
                    </n-button>
                    <n-button v-show="bCanvasActiveObject" class="toolbtn" circle size="large" @click="deleteActiveFigure"
                            style="background-color: rgba(255, 0, 0, 0.49);color: white;">
                        <n-icon><Delete /></n-icon>
                    </n-button>
                </div>
            </template>

        </SideDrawer>


    </div>
</template>

<style scoped>
.toolbtn {
    pointer-events: auto;
}
</style>


<script lang="ts" setup>
import { AppModel } from '../../../model/AppModel'
import {Canvas} from "../../../graph/Canvas"
import PartLib from "./PartLib.vue"
import SideDrawer from '../../common/SideDrawer.vue'
import SideSetting from "./SideSetting.vue"
import { FigureBase } from '../../../graph/FigureBase'
import { conn, Connection } from '../@beshell/conn-ts/Connection'
import { PartFigure } from '../../../graph/PartFigure'
import { PartSlaver } from '../../../model/parts/PartBase'
import { ref, onMounted, Ref} from 'vue'

import {ChevronLeft, Delete} from '@vicons/carbon'
import {PlusOutlined} from '@vicons/antd'
import {Options} from '@vicons/ionicons5'

// declare var $: any ;

const mapFigureTypeName: {[key:string]: string} = {
    'part': "零件" ,
    'wire': "连接线" ,
}


let model: AppModel

let canvas: Canvas ;

const bCanvasActiveObject = ref(false)

// const draggingNewPartClass = ref('')

const bDrawerPopout = ref(false)

const sDrawerBody = ref("none")

const refDrawer = ref(null) as unknown as Ref<typeof SideDrawer>
const refSetting = ref(null) as unknown as Ref<typeof SideSetting>

onMounted(function () {
})

function leave() {
    bDrawerPopout.value = false
}
function enter() {
    
}

function setModel(_model: AppModel) {
    model = _model
    if(_model) {
        loadModel(model)
    }
}

async function onNewPart(partClass:string, screenX:number, screenY:number){
    
    let newPart = model?.addPart(partClass)
    if(!newPart || !newPart.figure) {
        console.log(model,newPart)
        throw new Error("!newPart || !newPart.figure")
    }

    // 自动在主机零件上创建对象
    if(conn.isConnected) {

        let code = newPart.generateSetupCode()
        console.log(code)
        if(code) {
            conn.console.run(code)
        }

        if(newPart instanceof PartSlaver) {
            newPart.remoteSetup()
        }
    }
    
    // 开始拖动
    newPart.figure.startDragging(screenX, screenY, ()=>{})
}


function loadModel(model: AppModel) {

    if(canvas) {
        canvas.destroy()

        $(canvas.paperElement).off("mouseover", "**")
    }
    canvas = new Canvas()

    canvas.init("graph")

    setupFigureActiveHandle()
    
    setTimeout(()=>{
        canvas.loadFromModel(model)
    }, 0)

    // ;(window as any).graph = canvas.paperElement
}

function setupFigureActiveHandle() {

    let activeComin = false

    canvas.on("active", (figure: FigureBase)=>{
        activeComin = true
        bCanvasActiveObject.value = true
        if( !(['part', 'stud', 'wire']).includes(figure.type) ){
            bDrawerPopout.value = false
        }
        else {
            // 切换 figure setting
            if(bDrawerPopout.value) {
                refSetting.value.setTarget(figure.target)
            }
        }
    })
    canvas.on("unactive", ()=>{
        activeComin = false
        setTimeout(()=>{
            if(activeComin) // 切换活动figure, 不处理此次 unactive
                return
            bCanvasActiveObject.value = false
            bDrawerPopout.value = false
        }, 0)
    })
}

function openDrawer(body:string) {

    sDrawerBody.value = body
    bDrawerPopout.value = true

    if(body=='setting') {
        if(!canvas.activeFigure) {
            console.error("没有 activeFigure", canvas.activeFigure)
            return
        }
        ; refSetting.value.setTarget(canvas.activeFigure.target)
    }
}

function deleteActiveFigure() {
    let figure = canvas.activeFigure
    if(!figure || !figure.removable) {
        return
    }
    let type = mapFigureTypeName[figure.type]

    $dialog.create({
        title: '确定要删除选中的'+type+'吗？',
        positiveText: '确定', negativeText: '取消',
        onPositiveClick: () => {

        // 正在删除零件
        if(figure instanceof PartFigure) {
            // 远程主机 上 删除零件
            if(figure.part instanceof PartSlaver)
                removeRemotePart(figure.part) ;
            }

            canvas.removeFigre(figure)

        }
    })
}

async function removeRemotePart(part: PartSlaver) {
    console.log(`${part.remoteVar()}.deinit && ${part.remoteVar()}.deinit(); delete ${part.remoteVar()}`)
    conn.console.run(`${part.remoteVar()}.deinit && ${part.remoteVar()}.deinit(); delete ${part.remoteVar()}`)
}

function serialize() {
    return canvas.serialize()
}

defineExpose({
    leave,
    enter ,
    serialize,
    removeRemotePart, 
    setModel
})

</script>